/*
 * Copyright (c) 2024-2025.  little3201.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *       https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.leafage.exploiter.controller;

import io.leafage.exploiter.dto.ConnectionDTO;
import io.leafage.exploiter.service.ConnectionService;
import io.leafage.exploiter.vo.ConnectionVO;
import jakarta.validation.Valid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/connections")
public class ConnectionController {

    private static final Logger logger = LoggerFactory.getLogger(ConnectionController.class);

    private final ConnectionService ConnectionService;

    public ConnectionController(ConnectionService ConnectionService) {
        this.ConnectionService = ConnectionService;
    }

    /**
     * Retrieves a paginated list of records.
     *
     * @param page       The page number.
     * @param size       The number of records per page.
     * @param sortBy     The field to sort by.
     * @param descending Whether sorting should be in descending order.
     * @param name       The name filter for the schemas.
     * @return A paginated list of schemas, or 204 status code if an error occurs.
     */
    @GetMapping
    public ResponseEntity<Page<ConnectionVO>> retrieve(@RequestParam int page, @RequestParam int size,
                                                       String sortBy, boolean descending, String name) {
        Page<ConnectionVO> voPage;
        try {
            voPage = ConnectionService.retrieve(page, size, sortBy, descending, name);
        } catch (Exception e) {
            logger.error("Retrieve link error: ", e);
            return ResponseEntity.noContent().build();
        }
        return ResponseEntity.ok(voPage);
    }

    /**
     * Fetches a record by ID.
     *
     * @param id The record ID.
     * @return The record data, or 204 status code if an error occurs.
     */
    @GetMapping("/{id}")
    public ResponseEntity<ConnectionVO> fetch(@PathVariable Long id) {
        ConnectionVO vo;
        try {
            vo = ConnectionService.fetch(id);
        } catch (Exception e) {
            logger.error("Fetch link error: ", e);
            return ResponseEntity.noContent().build();
        }
        return ResponseEntity.ok(vo);
    }

    /**
     * Creates a new record.
     *
     * @param dto The record data transfer object.
     * @return The created record, or 417 status code if an error occurs.
     */
    @PostMapping
    public ResponseEntity<ConnectionVO> create(@RequestBody @Valid ConnectionDTO dto) {
        ConnectionVO vo;
        try {
            vo = ConnectionService.create(dto);
        } catch (Exception e) {
            logger.error("Create link error: ", e);
            return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).build();
        }
        return ResponseEntity.status(HttpStatus.CREATED).body(vo);
    }

    /**
     * Modifies an existing record.
     *
     * @param id  The record ID.
     * @param dto The record data transfer object.
     * @return The modified record, or 417 status code if an error occurs.
     */
    @PutMapping("/{id}")
    public ResponseEntity<ConnectionVO> modify(@PathVariable Long id, @RequestBody @Valid ConnectionDTO dto) {
        ConnectionVO vo;
        try {
            vo = ConnectionService.modify(id, dto);
        } catch (Exception e) {
            logger.error("Modify link error: ", e);
            return ResponseEntity.status(HttpStatus.NOT_MODIFIED).build();
        }
        return ResponseEntity.accepted().body(vo);
    }

    /**
     * Removes a record by ID.
     *
     * @param id The record ID.
     * @return 200 status code if successful, or 417 status code if an error occurs.
     */
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> remove(@PathVariable Long id) {
        try {
            ConnectionService.remove(id);
        } catch (Exception e) {
            logger.error("Remove link error: ", e);
            return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).build();
        }
        return ResponseEntity.ok().build();
    }

    /**
     * 根据所有表
     *
     * @return 查询的数据，异常时返回204状态码
     */
    @GetMapping("/{id}/tables")
    public ResponseEntity<List<String>> tables(@PathVariable Long id) {
        List<String> list;
        try {
            list = ConnectionService.tables(id);
        } catch (Exception e) {
            logger.error("Retrieve table error: ", e);
            return ResponseEntity.noContent().build();
        }
        return ResponseEntity.ok(list);
    }

}
